/* scheme.c
 * The run-time support needed for the Scheme->C compiler.
 * Programmer: Mayer Goldberg, 2000
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <debug.h>

#include "scheme.h"

/*** SUPPORT CODE ***/

string stringAlloc(int size)
{
	return (string)autoMalloc(size * sizeof(char)) ;
}

string stringCopy(string source)
{
	string target ;
	target = stringAlloc(1 + strlen(source));
	strcpy(target, source);
	return target ;
}

/*** MEMORY MANAGEMENT ***/


void *autoMalloc(int n)
{
	void *tmp;

	tmp = (void *)malloc(n);
	RUNTIME_ASSERT(tmp != NULL);
	return tmp;
}

void autoFree(void *p)
{
	if (p != NULL)
	{
    	free(p);
	}
}

/*** SCHEME SINGLETONS ***/

SchemeObjectData schemeTrueData = { .boolData = { .value = TRUE } } ;
SchemeObjectData schemeFalseData = { .boolData = { .value = FALSE } } ;

SchemeObject schemeTrueObj =
{
		.type = SCHEME_BOOL,
		.data = &schemeTrueData,
};
SchemeObject schemeFalseObj =
{
		.type = SCHEME_BOOL,
		.data = &schemeFalseData,
};
SchemeObject schemeNilObj =
{
		.type = SCHEME_NIL,
};
SchemeObject schemeVoidObj =
{
		.type = SCHEME_VOID,
};

SchemeObject* schemeTrue = &schemeTrueObj ;
SchemeObject* schemeFalse = &schemeFalseObj ;
SchemeObject* schemeNil = &schemeNilObj ;
SchemeObject* schemeVoid = &schemeVoidObj ;

/*** HELPERS ***/

SchemeObject* stackToSchemeList(LocalEnv stackTop, Amount elementCount)
{
	int i ;
	SchemeObject* result ;

	result = schemeNil ;
	for (i = elementCount-1 ; i >= 0 ; i--)
	{
		result = makeSchemePair(*(stackTop-i), result) ;
	}
	return result ;
}

Amount SchemeListLength(SchemeObject* head)
{
	Amount result = 0 ;
	while (!sobIsNil(head))
	{
		RUNTIME_ASSERT(sobIsPair(head)) ;
		result++ ;
		head = SOB_PAIR_CDR(head) ;
	}
	return result ;
}
